# Load COVID state-level data from NYT
cv_states <- as.data.frame(data.table::fread("https://raw.githubusercontent.com/nytimes/covid-19-data/master/us-states.csv"))
# Load state population data
state_pops <- as.data.frame(data.table::fread("https://raw.githubusercontent.com/COVID19Tracking/associated-data/master/us_census_data/us_census_2018_population_estimates_states.csv"))
state_pops$abb <- state_pops$state
state_pops$state <- state_pops$state_name
state_pops$state_name <- NULL
# Merge
cv_states <- merge(cv_states, state_pops, by="state")Lab 11
I. Reading and processing the New York Times (NYT) state-level COVID-19 data
1. Read in the data
2. Look at the data
# Inspect dimensions, head, and tail of the data
dim(cv_states)[1] 58094 9
head(cv_states) state date fips cases deaths geo_id population pop_density abb
1 Alabama 2023-01-04 1 1587224 21263 1 4887871 96.50939 AL
2 Alabama 2020-04-25 1 6213 213 1 4887871 96.50939 AL
3 Alabama 2023-02-26 1 1638348 21400 1 4887871 96.50939 AL
4 Alabama 2022-12-03 1 1549285 21129 1 4887871 96.50939 AL
5 Alabama 2020-05-06 1 8691 343 1 4887871 96.50939 AL
6 Alabama 2021-04-21 1 524367 10807 1 4887871 96.50939 AL
tail(cv_states) state date fips cases deaths geo_id population pop_density abb
58089 Wyoming 2022-09-11 56 175290 1884 56 577737 5.950611 WY
58090 Wyoming 2022-08-21 56 173487 1871 56 577737 5.950611 WY
58091 Wyoming 2021-01-26 56 51152 596 56 577737 5.950611 WY
58092 Wyoming 2021-02-21 56 53795 662 56 577737 5.950611 WY
58093 Wyoming 2021-08-22 56 70671 809 56 577737 5.950611 WY
58094 Wyoming 2021-03-20 56 55581 693 56 577737 5.950611 WY
# Inspect the structure of the variables
str(cv_states)'data.frame': 58094 obs. of 9 variables:
$ state : chr "Alabama" "Alabama" "Alabama" "Alabama" ...
$ date : IDate, format: "2023-01-04" "2020-04-25" ...
$ fips : int 1 1 1 1 1 1 1 1 1 1 ...
$ cases : int 1587224 6213 1638348 1549285 8691 524367 1321892 1088370 1153149 814025 ...
$ deaths : int 21263 213 21400 21129 343 10807 19676 16756 16826 15179 ...
$ geo_id : int 1 1 1 1 1 1 1 1 1 1 ...
$ population : int 4887871 4887871 4887871 4887871 4887871 4887871 4887871 4887871 4887871 4887871 ...
$ pop_density: num 96.5 96.5 96.5 96.5 96.5 ...
$ abb : chr "AL" "AL" "AL" "AL" ...
The “state” and “abb” variables could be factors instead of characters.
3. Format the data
# Make the date into a date variable
cv_states$date <- as.Date(cv_states$date, format="%Y-%m-%d")
# Format the state and state abbreviation (abb) variables
state_list <- unique(cv_states$state)
cv_states$state <- factor(cv_states$state, levels = state_list)
abb_list <- unique(cv_states$abb)
cv_states$abb <- factor(cv_states$abb, levels = abb_list)
# Order the data first by state, second by date
cv_states = cv_states[order(cv_states$state, cv_states$date),]
# Confirm the variables are now correctly formatted
str(cv_states)'data.frame': 58094 obs. of 9 variables:
$ state : Factor w/ 52 levels "Alabama","Alaska",..: 1 1 1 1 1 1 1 1 1 1 ...
$ date : Date, format: "2020-03-13" "2020-03-14" ...
$ fips : int 1 1 1 1 1 1 1 1 1 1 ...
$ cases : int 6 12 23 29 39 51 78 106 131 157 ...
$ deaths : int 0 0 0 0 0 0 0 0 0 0 ...
$ geo_id : int 1 1 1 1 1 1 1 1 1 1 ...
$ population : int 4887871 4887871 4887871 4887871 4887871 4887871 4887871 4887871 4887871 4887871 ...
$ pop_density: num 96.5 96.5 96.5 96.5 96.5 ...
$ abb : Factor w/ 52 levels "AL","AK","AZ",..: 1 1 1 1 1 1 1 1 1 1 ...
head(cv_states) state date fips cases deaths geo_id population pop_density abb
1029 Alabama 2020-03-13 1 6 0 1 4887871 96.50939 AL
597 Alabama 2020-03-14 1 12 0 1 4887871 96.50939 AL
282 Alabama 2020-03-15 1 23 0 1 4887871 96.50939 AL
12 Alabama 2020-03-16 1 29 0 1 4887871 96.50939 AL
266 Alabama 2020-03-17 1 39 0 1 4887871 96.50939 AL
78 Alabama 2020-03-18 1 51 0 1 4887871 96.50939 AL
tail(cv_states) state date fips cases deaths geo_id population pop_density abb
57902 Wyoming 2023-03-18 56 185640 2009 56 577737 5.950611 WY
57916 Wyoming 2023-03-19 56 185640 2009 56 577737 5.950611 WY
57647 Wyoming 2023-03-20 56 185640 2009 56 577737 5.950611 WY
57867 Wyoming 2023-03-21 56 185800 2014 56 577737 5.950611 WY
58057 Wyoming 2023-03-22 56 185800 2014 56 577737 5.950611 WY
57812 Wyoming 2023-03-23 56 185800 2014 56 577737 5.950611 WY
# Inspect the range values for each variable. What is the date range? The range of cases and deaths?
summary(cv_states) state date fips cases
Washington : 1158 Min. :2020-01-21 Min. : 1.00 Min. : 1
Illinois : 1155 1st Qu.:2020-12-06 1st Qu.:16.00 1st Qu.: 112125
California : 1154 Median :2021-09-11 Median :29.00 Median : 418120
Arizona : 1153 Mean :2021-09-10 Mean :29.78 Mean : 947941
Massachusetts: 1147 3rd Qu.:2022-06-17 3rd Qu.:44.00 3rd Qu.: 1134318
Wisconsin : 1143 Max. :2023-03-23 Max. :72.00 Max. :12169158
(Other) :51184
deaths geo_id population pop_density
Min. : 0 Min. : 1.00 Min. : 577737 Min. : 1.292
1st Qu.: 1598 1st Qu.:16.00 1st Qu.: 1805832 1st Qu.: 43.659
Median : 5901 Median :29.00 Median : 4468402 Median : 107.860
Mean : 12553 Mean :29.78 Mean : 6397965 Mean : 423.031
3rd Qu.: 15952 3rd Qu.:44.00 3rd Qu.: 7535591 3rd Qu.: 229.511
Max. :104277 Max. :72.00 Max. :39557045 Max. :11490.120
NA's :1106
abb
WA : 1158
IL : 1155
CA : 1154
AZ : 1153
MA : 1147
WI : 1143
(Other):51184
min(cv_states$date)[1] "2020-01-21"
max(cv_states$date)[1] "2023-03-23"
The date range is January 21, 2020 to March 23, 2023. The range of cases is 1 to 12169158. The range of deaths is 0 to 104277.
4. Add new_cases and new_deaths and correct outliers
# Add variables for new_cases and new_deaths:
for (i in 1:length(state_list)) {
cv_subset = subset(cv_states, state == state_list[i])
cv_subset = cv_subset[order(cv_subset$date),]
# Add starting level for new cases and deaths
cv_subset$new_cases = cv_subset$cases[1]
cv_subset$new_deaths = cv_subset$deaths[1]
# Calculate new cases and new deaths for each date
for (j in 2:nrow(cv_subset)) {
cv_subset$new_cases[j] <- cv_subset$cases[j] - cv_subset$cases[j - 1]
cv_subset$new_deaths[j] <- cv_subset$deaths[j] - cv_subset$deaths[j - 1]
}
# Include in main dataset
cv_states$new_cases[cv_states$state==state_list[i]] = cv_subset$new_cases
cv_states$new_deaths[cv_states$state==state_list[i]] = cv_subset$new_deaths
}
# Focus on recent dates
cv_states <- cv_states |> dplyr::filter(date >= "2021-06-01")# Inspect outliers in new_cases using plotly
library(ggplot2)
library(plotly)
Attaching package: 'plotly'
The following object is masked from 'package:ggplot2':
last_plot
The following object is masked from 'package:stats':
filter
The following object is masked from 'package:graphics':
layout
p1<-ggplot(cv_states, aes(x = date, y = new_cases, color = state)) +
geom_line() +
geom_point(size = .5, alpha = 0.5)
ggplotly(p1)p1<-NULLp2<-ggplot(cv_states, aes(x = date, y = new_deaths, color = state)) +
geom_line() +
geom_point(size = .5, alpha = 0.5)
ggplotly(p2)p2<-NULL # to clear from workspaceNew cases:
Strange values:
- On 2021-06-04, Florida has -40527 cases, which does not make sense.
- On 2022-01-29, Colorado has -4678 cases.
- On 2022-02-08, Pennsylvania has -4397 cases.
Possible outliers:
- On 2022-01-10, California had 227,972 new cases.
- On 2022-01-17, California had 221,235 new cases.
New deaths:
Strange values:
- On 2021-06-04, California had -375 new deaths
- On 2022-04–5, West Virginia has -123 new deaths.
Possible outliers:
- On 2022-11-11, New York had 3732 new deaths.
- On 2022-11-11, California had 2363 new deaths.
# Set negative new case or death counts to 0
cv_states$new_cases[cv_states$new_cases<0] = 0
cv_states$new_deaths[cv_states$new_deaths<0] = 0
# Recalculate `cases` and `deaths` as cumulative sum of updated `new_cases` and `new_deaths`
for (i in 1:length(state_list)) {
cv_subset = subset(cv_states, state == state_list[i])
# Add starting level for cases and death
cv_subset$cases = cv_subset$new_cases[1]
cv_subset$deaths = cv_subset$new_deaths[1]
#Calculate cases and death as cumulative sum of new_cases and new_deaths
for (j in 2:nrow(cv_subset)) {
cv_subset$cases[j] = cv_subset$new_cases[j] + cv_subset$cases[j-1]
cv_subset$deaths[j] = cv_subset$new_deaths[j] + cv_subset$deaths[j-1]
}
# include in main dataset
cv_states$cases[cv_states$state==state_list[i]] = cv_subset$cases
cv_states$deaths[cv_states$state==state_list[i]] = cv_subset$deaths
}
# Smooth new counts
cv_states$new_cases = zoo::rollmean(cv_states$new_cases, k=7, fill=NA, align='right') %>% round(digits = 0)
cv_states$new_deaths = zoo::rollmean(cv_states$new_deaths, k=7, fill=NA, align='right') %>% round(digits = 0)# Inspect data again interactively
p2<-ggplot(cv_states, aes(x = date, y = new_deaths, color = state)) + geom_line() + geom_point(size = .5, alpha = 0.5)
ggplotly(p2)#p2=NULLSome outliers:
On 2022-11-11, New York had 553 deaths
On 2021-12-28, Tennessee had 363 deaths
On 2021-11-24, Missouri had 340 deaths
5. Add additional variables
# Add population normalized (by 100,000) counts for each variable
cv_states$per100k = as.numeric(format(round(cv_states$cases/(cv_states$population/100000),1),nsmall=1))
cv_states$newper100k = as.numeric(format(round(cv_states$new_cases/(cv_states$population/100000),1),nsmall=1))Warning: NAs introduced by coercion
cv_states$deathsper100k = as.numeric(format(round(cv_states$deaths/(cv_states$population/100000),1),nsmall=1))
cv_states$newdeathsper100k = as.numeric(format(round(cv_states$new_deaths/(cv_states$population/100000),1),nsmall=1))Warning: NAs introduced by coercion
# add a naive_CFR variable = deaths / cases
cv_states = cv_states |> mutate(naive_CFR = round((deaths*100/cases),2))
# create a `cv_states_today` variable
cv_states_today = subset(cv_states, date==max(cv_states$date))II. Scatterplots
6. Explore scatterplots using plot_ly()
Pop_density vs cases
# pop_density vs. cases
cv_states_today |>
plot_ly(x = ~pop_density, y = ~cases,
type = 'scatter',
mode = 'markers',
color = ~state,
size = ~population, sizes = c(5, 70), marker = list(sizemode='diameter', opacity=0.5))Warning: Ignoring 1 observations
Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
District of Columbia is an outlier.
# filter out "District of Columbia"
cv_states_today_filter <- cv_states_today |> filter(state!="District of Columbia")
# pop_density vs cases after filtering
cv_states_today_filter |>
plot_ly(x = ~pop_density, y = ~cases,
type = 'scatter',
mode = 'markers',
color = ~state,
size = ~population, sizes = c(5, 70), marker = list(sizemode='diameter', opacity=0.5))Warning: Ignoring 1 observations
Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
Pop_density vs cases per 100k
# pop_density vs cases per 100k
cv_states_today |>
plot_ly(x = ~pop_density, y = ~per100k,
type = 'scatter',
mode = 'markers',
color = ~state,
size = ~population, sizes = c(5, 70), marker = list(sizemode='diameter', opacity=0.5))Warning: Ignoring 1 observations
Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
District of Columbia is an outlier again.
# pop_density vs cases per 100k after filtering
cv_states_today_filter |>
plot_ly(x = ~pop_density, y = ~per100k,
type = 'scatter',
mode = 'markers',
color = ~state,
size = ~population, sizes = c(5, 70), marker = list(sizemode='diameter', opacity=0.5))Warning: Ignoring 1 observations
Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
Pop_density vs deaths
#pop_density vs deaths
cv_states_today |>
plot_ly(x = ~pop_density, y = ~deaths,
type = 'scatter',
mode = 'markers',
color = ~state,
size = ~population, sizes = c(5, 70), marker = list(sizemode='diameter', opacity=0.5))Warning: Ignoring 1 observations
Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
District of Columbia is an outlier again.
cv_states_today_filter |>
plot_ly(x = ~pop_density, y = ~deaths,
type = 'scatter',
mode = 'markers',
color = ~state,
size = ~population, sizes = c(5, 70), marker = list(sizemode='diameter', opacity=0.5))Warning: Ignoring 1 observations
Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
Pop_density vs deaths per 100k
cv_states_today |>
plot_ly(x = ~pop_density, y = ~deathsper100k,
type = 'scatter',
mode = 'markers',
color = ~state,
size = ~population, sizes = c(5, 70), marker = list(sizemode='diameter', opacity=0.5))Warning: Ignoring 1 observations
Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
District of columbia is an outlier again.
cv_states_today_filter |>
plot_ly(x = ~pop_density, y = ~deathsper100k,
type = 'scatter',
mode = 'markers',
color = ~state,
size = ~population, sizes = c(5, 70), marker = list(sizemode='diameter', opacity=0.5))Warning: Ignoring 1 observations
Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
Choose one plot
cv_states_today_filter |>
plot_ly(x = ~pop_density, y = ~per100k,
type = 'scatter',
mode = 'markers',
color = ~state,
size = ~population, sizes = c(5, 70), marker = list(sizemode='diameter', opacity=0.5),
hoverinfo = 'text',
text = ~paste( paste(state, ":", sep=""),
paste(" Cases per 100k: ", per100k, sep=""),
paste(" Deaths per 100k: ", deathsper100k, sep=""),
sep = "<br>")) |>
layout(title = "Population-normalized COVID-19 deaths (per 100k) vs. Population density for US States",
yaxis = list(title = "Cases per 100k"),
xaxis = list(title = "Population Density"),
hovermode = "compare")Warning: Ignoring 1 observations
Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
7. Explore scatterplot trend interactively using ggplotly() and geom_smooth()
p <- ggplot(cv_states_today_filter, aes(x=pop_density, y=newdeathsper100k, size=population)) +
geom_point() +
geom_smooth()
ggplotly(p)`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
Warning: Removed 1 row containing non-finite outside the scale range
(`stat_smooth()`).
Warning: The following aesthetics were dropped during statistical transformation: size.
ℹ This can happen when ggplot fails to infer the correct grouping structure in
the data.
ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
variable into a factor?
Most of the states have a population density between 0 and 250. The slope of the line beyond that point is primarily dictated by a handful of states. When looking at the points between 0 and 250 pop_density, it appears that there is no relationship between pop_density and new deaths per 100k. Overall, I do not think population density and new deaths per 100k are correlated.
8. Multiple line chart
# Line chart for naive_CFR for all states over time using `plot_ly()`
plot_ly(cv_states, x = ~date, y = ~naive_CFR, color = ~state, type = "scatter", mode = "lines")Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
The states that had an increase in CFR in September 2021 included Arkansas, Florida, Georgia, Hawaii, Idaho, Indiana, Kentucky, Louisiana, Mississippi, Nevada, Oklahoma, Oregon, Puerto Rico, South Carolina, Texas, and West Virginia. The CFR continued to increase until January 2022. It dipped in January 2022 and then slightly increased and plateaued in March 2022.
# Line chart for Florida showing new_cases and new_deaths together
cv_states |> filter(state=="Florida") |>
plot_ly(x = ~date, y = ~new_cases, type = "scatter", mode = "lines", name = "New Cases") |>
add_trace(x = ~date, y = ~new_deaths, type = "scatter", mode = "lines", name = "New Deaths") The approximate peak of deaths is 445 deaths on September 9, 2021. The approximate peak of cases is 84.699k cases on January 10, 2022. However, the approximate peak of cases corresponding to the peak of deaths is 29.711k cases on August 16, 2021. The time delay between the peak of cases and the peak of deaths is 24 days.
9. Heatmaps
# Map state, date, and new_cases to a matrix
library(tidyr)
cv_states_mat <- cv_states |> select(state, date, new_cases) |> dplyr::filter(date>as.Date("2021-06-15"))
cv_states_mat2 <- as.data.frame(pivot_wider(cv_states_mat,
names_from = state,
values_from = new_cases))
rownames(cv_states_mat2) <- cv_states_mat2$date
cv_states_mat2$date <- NULL
cv_states_mat2 <- as.matrix(cv_states_mat2)
# Create a heatmap using plot_ly()
plot_ly(x=colnames(cv_states_mat2), y=rownames(cv_states_mat2),
z=~cv_states_mat2,
type="heatmap",
showscale=T)California stands out.
# Repeat with newper100k
cv_states_mat <- cv_states |> select(state, date, newper100k) |> dplyr::filter(date>as.Date("2021-06-15"))
cv_states_mat2 <- as.data.frame(pivot_wider(cv_states_mat,
names_from = state,
values_from = newper100k))
rownames(cv_states_mat2) <- cv_states_mat2$date
cv_states_mat2$date <- NULL
cv_states_mat2 <- as.matrix(cv_states_mat2)
plot_ly(x=colnames(cv_states_mat2), y=rownames(cv_states_mat2),
z=~cv_states_mat2,
type="heatmap",
showscale=T)Now, Rhode Island sticks out.
# Create a second heatmap after filtering to only include dates every other week
filter_dates <- seq(as.Date("2021-06-15"), as.Date("2021-11-01"), by="2 weeks")
cv_states_mat <- cv_states |> select(state, date, new_cases) |> filter(date %in% filter_dates)
cv_states_mat2 <- as.data.frame(pivot_wider(cv_states_mat,
names_from = state,
values_from = new_cases))
rownames(cv_states_mat2) <- cv_states_mat2$date
cv_states_mat2$date <- NULL
cv_states_mat2 <- as.matrix(cv_states_mat2)
# Create a heatmap using plot_ly()
plot_ly(x=colnames(cv_states_mat2), y=rownames(cv_states_mat2),
z=~cv_states_mat2,
type="heatmap",
showscale=T)10. Map
### For specified date
pick.date = "2021-10-15"
# Extract the data for each state by its abbreviation
cv_per100 <- cv_states |> filter(date==pick.date) |> select(state, abb, newper100k, cases, deaths, naive_CFR) # select data
cv_per100$state_name <- cv_per100$state
cv_per100$state <- cv_per100$abb
cv_per100$abb <- NULL
# Create hover text
cv_per100$hover <- with(cv_per100, paste(state_name, '<br>',
"Naive CFR: ", naive_CFR, '<br>',
"Cases per 100k: ", newper100k, '<br>',
"Cases: ", cases, '<br>',
"Deaths: ", deaths))
# Set up mapping details
set_map_details <- list(
scope = 'usa',
projection = list(type = 'albers usa'),
showlakes = TRUE,
lakecolor = toRGB('white')
)
# Make sure both maps are on the same color scale
shadeLimit <- 2
# Create the map
fig <- plot_geo(cv_per100, locationmode = 'USA-states') |>
add_trace(
z = ~naive_CFR, text = ~hover, locations = ~state,
color = ~naive_CFR, colors = 'Purples'
)
fig <- fig |> colorbar(title = paste0("Naive CFR: ", pick.date), limits = c(0,shadeLimit))
fig <- fig |> layout(
title = paste('Naive Case Fatality Rates (CFRs) by State as of ', pick.date, '<br>(Hover for value)'),
geo = set_map_details
)
fig_pick.date <- fig
#############
### Map for today's date
# Extract the data for each state by its abbreviation
cv_per100 <- cv_states_today |> select(state, abb, newper100k, cases, deaths, naive_CFR) # select data
cv_per100$state_name <- cv_per100$state
cv_per100$state <- cv_per100$abb
cv_per100$abb <- NULL
# Create hover text
cv_per100$hover <- with(cv_per100, paste(state_name, '<br>',
"Naive CFR: ", naive_CFR, '<br>',
"Cases per 100k: ", newper100k, '<br>',
"Cases: ", cases, '<br>',
"Deaths: ", deaths))
# Set up mapping details
set_map_details <- list(
scope = 'usa',
projection = list(type = 'albers usa'),
showlakes = TRUE,
lakecolor = toRGB('white')
)
# Create the map
fig <- plot_geo(cv_per100, locationmode = 'USA-states') |>
add_trace(
z = ~naive_CFR, text = ~hover, locations = ~state,
color = ~naive_CFR, colors = 'Purples'
)
fig <- fig |> colorbar(title = paste0("Naive CFR: ", Sys.Date()), limits = c(0,shadeLimit))
fig <- fig |> layout(
title = paste('Naive Case Fatality Rates (CFRs) by State as of', Sys.Date(), '<br>(Hover for value)'),
geo = set_map_details
)
fig_Today <- fig
### Plot together
subplot(fig_pick.date, fig_Today, nrows = 2, margin = .05)On 2021-10-15, the CFRs were highest in Nevada (1.57) and Florida (1.57). Other states with high CFRs included Idaho, Texas, Arkansas, Mississippi, Alabama, and Georgia.
On 2024-11-12, Texas no longer has the highest CFR. The rest of the states generally followa similar pattern as in October 2021 in terms of relative CFRs. The Southeast region and Southwest have the higher CFRs. The Midwest and California have lower CFRs.